#pragma once

#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include "Comm.hpp"

class Epoller
{
public:
    Epoller()
    {
        _epfd = epoll_create(128);
        if(_epfd < 0)
        {
            LOG(FATAL, "epoll_create fail\n");
            exit(EPOLLCRATERROR);
        }
        LOG(INFO, "epoll create success!, epfd: %d\n", _epfd);
    }

    void AddEvent(int fd, uint32_t events)
    {
        epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        if(epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
        {
            LOG(ERROR, "将fd: %d 添加进epoll模型中失败\n", fd);
            return;
        }
        LOG(INFO, "将fd: %d 添加进epoll模型中成功\n", fd);
    }

    void ModifyEvent(int fd, uint32_t events)
    {
        epoll_event ev;
        ev.data.fd = fd;
        ev.events = events;
        if(epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &ev))
        {
            LOG(ERROR, "将fd: %d 关心事件修改失败\n", fd);
            return;
        }
        LOG(INFO, "将fd: %d 关心事件修改成功\n", fd);
    }

    void DelEvents(int fd)
    {
        if(epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr))
        {
            LOG(ERROR, "将fd: %d 关心事件删除失败\n", fd);
            return;
        }
        LOG(INFO, "将fd: %d 关心事件删除成功\n", fd);
    }

    int Wait(epoll_event events[], int size, int timeout)
    {
        return epoll_wait(_epfd, events, size, timeout);
    }

    ~Epoller()
    {
        if(_epfd < 0)
        {
            ::close(_epfd);
        }
    }
private:
    int _epfd;
};